//
// Created by 赵中恒 on 2/1/21.
//

#include "zh_safe.h"

//开启循环轮训检查TracePid字段
void *thread_function(void *argv) {
    int pid = getpid();
    char file_name[20] = {'\0'};
    sprintf(file_name, "/proc/%d/status", pid);
    char linestr[256];
    int i = 0;
    FILE *fp;
    while (1) {
        i = 0;
        fp = fopen(file_name, "r");
        if (fp == NULL) {
            break;
        }
        while (!feof(fp)) {
            fgets(linestr, 256, fp);
            int res = get_real_number_for_str(linestr, TracerPid, start);
            if (res != 0) {
                exit(0);
            }
            i++;
        }
        fclose(fp);
        sleep(5);
    }
    return ((void *) 0);
}

//开启循环轮训检查TracePid字段
void *thread_function_server(void *argv) {
    while (1) {
        char *cmd = "ps -ef | grep 'server'";
        FILE *fp;
        char buffer[1024];
        fp = popen(cmd, "r");
        fgets(buffer, sizeof(buffer), fp);
        //printf("%s", buffer);

        while (fgets(buffer, 1024, fp) != NULL) {
            LOGD("------: %s", buffer);
            if (strstr(buffer, "lldb-server") != NULL) {
                exit(0);
            }
            if (strstr(buffer, "gdbserver") != NULL) {
                exit(0);
            }
        }
        pclose(fp);
        sleep(5);
    }
    return ((void *) 0);
}

//开启循环轮训检查LLDB字段
void *thread_function_lldb_server(void *argv) {
    char *path = (char *) (argv);
    LOGD("--------------- 7 path : %s", path);
    while (1) {
        LOGD("--------------- tmp");
        DIR *dir = opendir("/data/data/");
        if (dir != NULL) {
            struct dirent *file;
            // read all the files in dir
            while ((file = readdir(dir)) != NULL) {
                char *fileName = file->d_name;
                LOGD("--------------- 8 path : %s", fileName);
                if (strstr(fileName, "lldb")) {
                    exit(0);
                }
            }
            closedir(dir);
        }


        closedir(dir);
        sleep(5);
    }
    return ((void *) 0);
}
/**
 * 检测TracerId是否为0.
 */
extern "C"
JNIEXPORT jint JNICALL
Java_com_zzh_lib_protector_ZHAppSafe_startSafePrevent(JNIEnv *env, jclass clazz, jboolean exit,
                                                      jobject callback) {


    pthread_t t_id;
    int err = pthread_create(&t_id, NULL, thread_function, NULL);
    if (err != 0) {
        return err;
    }
    return err;
}



extern "C"
JNIEXPORT jint JNICALL
Java_com_zzh_lib_protector_ZHAppSafe_startSafePreventServer(JNIEnv *env, jclass clazz,
                                                            jboolean exit, jobject callback) {
    pthread_t t_id;
    int err = pthread_create(&t_id, NULL, thread_function_server, NULL);
    if (err != 0) {
        return err;
    }
    return err;
}


extern "C"
JNIEXPORT jint JNICALL
Java_com_zzh_lib_protector_ZHAppSafe_startSafePreventPathServer(JNIEnv *env, jclass clazz,
                                                                jboolean exits, jstring path,
                                                                jobject callback) {
    if (path == NULL) {
        exit(0);
    }

    jstring str = env->NewStringUTF("/data/data/");
    jstring end = env->NewStringUTF("/");
    jclass String_clazz = env->FindClass("java/lang/String");

    jmethodID concat_methodID = env->GetMethodID(String_clazz, "concat",
                                                 "(Ljava/lang/String;)Ljava/lang/String;");
    ///====================================
    //需要在后面拼接的字符串...

    jobject str1 = env->CallObjectMethod(str, concat_methodID, path);
    jobject str2 = env->CallObjectMethod((jstring) str1, concat_methodID, end);

    const char *chars = env->GetStringUTFChars((jstring) str2, 0);

    LOGD("拼接后字符 ===> %s ", chars);
    //释放内存
    env->DeleteLocalRef(str);
    env->DeleteLocalRef(end);
    env->DeleteLocalRef(str1);
    env->ReleaseStringUTFChars((jstring) str2, chars);

    pthread_t t_id;
    int err = pthread_create(&t_id, NULL, thread_function_lldb_server, (void *) chars);
    if (err != 0) {
        return err;
    }
    return 0;
}
extern "C"
JNIEXPORT jint JNICALL
Java_com_zzh_lib_protector_ZHAppSafe_safeKillSelfServer(JNIEnv *env, jclass clazz) {
    return killpg(getpgid(getpid()), 9);
}